package cn.newhopedairy.delivery.api;

import cn.newhopedairy.common.wrapper.R;
import cn.newhopedairy.delivery.command.DeclareGoodsCmd;
import cn.newhopedairy.delivery.command.DeliveryInfoCmd;
import cn.newhopedairy.delivery.response.DeliveryOrderResp;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDate;
import java.util.List;

/**
 * 配送单API
 *
 * 注：当既是服务提供者又是消费者时，@RequestMapping注解不能放在类前
 *
 * @author Neo.Li
 * @date 2020-09-25 15:28
 */
@RequestMapping("/delivery-orders")
@Api(tags = "配送单API")
public interface DeliveryOrderApi {
    /**
     * 根据送货员获取配送单列表
     *
     * @param deliveryManId 送货员Id
     * @param deliveryDate 配送时间
     * @return 配送单列表
     */
    @ApiOperation("根据送货员获取配送单列表")
    @GetMapping("/byMan")
    R<List<DeliveryOrderResp>> getDeliveryOrdersByManId(@ApiParam("送货员Id") @RequestParam("deliveryManId") Long deliveryManId,
                                                 @ApiParam("配送时间") @RequestParam(name = "deliveryDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate deliveryDate);

    /**
     * 根据收货人获取配送单列表
     *
     * @param consigneeId 收货人Id
     * @return 配送单列表
     */
    @ApiOperation("根据收货人获取配送单列表")
    @GetMapping("/")
    R<List<DeliveryOrderResp>> getDeliveryOrders(@ApiParam("收货人Id") @RequestParam("consigneeId") Long consigneeId);

    /**
     * 获取配送单详情
     *
     * @param deliveryOrderId 配送单Id
     * @return 配送单详情
     */
    @ApiOperation("获取配送单详情")
    @GetMapping("/{deliveryOrderId}")
    R<DeliveryOrderResp> getDeliveryOrder(@ApiParam("配送单Id") @PathVariable("deliveryOrderId") Long deliveryOrderId);

    /**
     * 站点报货，由于报货比较耗时，采用排队机制，由任务调度服务或者手工触发，见方法{@link #triggerDeclareGoods}
     *
     * @param declareGoodsCmd 报货申请
     * @return
     */
    @ApiOperation("站点报货")
    @PostMapping("/declare")
    R<Void> declareGoodsToFactory(@ApiParam("报货申请") @RequestBody DeclareGoodsCmd declareGoodsCmd);

    /**
     * 触发站点报货，由任务调度服务触发，或者手工触发均可
     *
     * @return
     */
    @ApiOperation("触发站点报货")
    @GetMapping("/declare/trigger")
    R<Void> triggerDeclareGoods();

    /**
     * 前端查询报货状态
     *
     * @param stationId 站点
     * @return
     */
    @GetMapping("/declare/status")
    R<String> declareGoodsStatus(@ApiParam("站点Id") @RequestParam("stationId") Long stationId);

    /**
     * 创建配送单，下单支付后触发生成配送单，周期性配送定时自动生成
     *
     * @param deliveryInfoCmd 配送信息
     * @return 配送单标识
     */
    @ApiOperation("创建配送单")
    @PostMapping("/")
    R<Long> createDeliveryOrder(@RequestBody @Valid DeliveryInfoCmd deliveryInfoCmd);

    /**
     * 批量创建配送单
     *
     * @param deliveryInfoCmds 配送信息
     * @return 配送单标识
     */
    @ApiOperation("批量创建配送单")
    @PostMapping("/patch")
    R<List<Long>> createDeliveryOrders(@RequestBody @Valid List<DeliveryInfoCmd> deliveryInfoCmds);

    /**
     * 配送单送达
     *
     * @param deliveryOrderId 配送单Id
     * @return 配送单Id
     */
    @ApiOperation("配送单送达")
    @PutMapping("/{deliveryOrderId}/delivered")
    R<Long> deliveredDeliveryOrder(@PathVariable("deliveryOrderId") Long deliveryOrderId);

    /**
     * 配送单拒收，由客户发起拒收
     *
     * @param deliveryOrderId 配送单Id
     * @return 配送单Id
     */
    @ApiOperation("配送单拒收")
    @PutMapping("/{deliveryOrderId}/refuse")
    R<Long> refuseDeliveryOrder(@PathVariable("deliveryOrderId") Long deliveryOrderId);

    /**
     * 配送单缺货，可能是配送过程中损坏、或者生产量不足，通知客户并顺延
     *
     * @param deliveryOrderId 配送单Id
     * @return 配送单Id
     */
    @ApiOperation("配送单缺货")
    @PutMapping("/{deliveryOrderId}/lack")
    R<Long> lackDeliveryOrder(@PathVariable("deliveryOrderId") Long deliveryOrderId);
}
